package com.jenkin.jcache.realize;

import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import com.jenkin.jcache.base.IListCache;

/**
 * 列表缓存
 * @author yangjie
 *
 */
public class ListCache<E> implements IListCache<E> {
	
	private volatile CopyOnWriteArrayList<E> copyOnWriteArrayList = null;
	
	private int expirationSeconds = 0;
	
	private volatile Calendar expirationTime;
	
	private FillListener fillListener;
	
	ListCache(CopyOnWriteArrayList<E> copyOnWriteArrayList, int expirationSeconds, Calendar expirationTime){
		this.copyOnWriteArrayList = copyOnWriteArrayList;
		this.expirationSeconds = expirationSeconds;
		this.expirationTime = expirationTime;
	}
	
	/**
	 * 根据下标得到对象，会进行缓存过期检查，如果缓存已过期就调用用户自定义的填充数据方法
	 */
	public E get(int i) {
		isPastDue();
		return copyOnWriteArrayList.get(i);
	}
	
	/**
	 * 得到所有集合，会进行缓存过期检查，如果缓存已过期就调用用户自定义的填充数据方法
	 */
	public List<E> getList(){
		isPastDue();
		return copyOnWriteArrayList;
	}
	
	/**
	 * 得到集合数据，会进行缓存过期检查，如果缓存已过期就调用用户自定义的填充数据方法
	 */
	public int size() {
		isPastDue();
		return copyOnWriteArrayList.size();
	}
	
	/**
	 * 添加缓存数据，不会进行缓存过期检查
	 */
	public boolean add(E item) {
		return copyOnWriteArrayList.add(item);
	}
	
	/**
	 * 移除缓存数据，不会进行缓存过期检查
	 */
	public E remove(int i) {
		return copyOnWriteArrayList.remove(i);
	}
	
	/**
	 * 清空缓存，不会进行缓存过期检查
	 */
	public void clear() {
		copyOnWriteArrayList.clear();
	}
	
	/**
	 * 添加填充数据的方法
	 * @param fillListener
	 */
	public void addFillListener(FillListener fillListener) {
		this.fillListener = fillListener;
	}
	
	/**
	 * 缓存是否已过期，如果过期就调用用户自定义的填充数据方法
	 */
	private void isPastDue() {
		if (expirationSeconds != 0 && expirationTime.before(Calendar.getInstance())) {
			synchronized(this) {
				if (expirationTime.before(Calendar.getInstance())) {
					if (fillListener != null) {
						fillListener.run();
						expirationTime.add(Calendar.SECOND, expirationSeconds);
					}
				}
			}
		}
	}

}
